﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using DomainModel.Abstract;
using DomainModel.Entities;

namespace WebSite.Controllers
{
    // The Controller for dealing with views regarding the hiring specialists ability to call people for interviews.
    [Authorize(Roles = "HiringSpecialist")]
    public class PhoneInterviewController : Controller
    {
        // The database abstractions for the applicants progress, applications, positions, jobs,
        // job histories, personal references, and educations.
        private IApplicantsProgressRepository applicantsProgressRepository;
        private IApplicationsRepository applicationsRepository;
        private IPositionsRepository positionsRepository;
        private IJobsRepository jobsRepository;
        private IJobHistoriesRepository jobHistoriesRepository;
        private IPersonalReferencesRepository personalReferencesRepository;
        private IEducationsRepository educationsRepository;
        private IQuestionnaireEntriesRepository questionnaireEntriesRepository;
        private IQuestionsRepository questionsRepository;
        private IAnswersRepository answersRepository;
        private IAnsweredQuestionsRepository answeredQuestionsRepository;

        // Constructor, it attachs the applicants progress repository, the applications repository,
        // and the positions repository, the jobs repository, the jobs history repository, the educations repository 
        // and the personal references repository to the controller.
        public PhoneInterviewController(IApplicantsProgressRepository applicantsProgressRepository, 
                                    IApplicationsRepository applicationsRepository,
                                    IPositionsRepository positionsRepository,
                                    IJobsRepository jobsRepository,
                                    IJobHistoriesRepository jobHistoriesRepository,
                                    IPersonalReferencesRepository personalReferencesRepository,
                                    IEducationsRepository educationsRepository,
                                    IQuestionnaireEntriesRepository questionnaireEntriesRepository,
                                    IQuestionsRepository questionsRepository,
                                    IAnswersRepository answersRepository,
                                    IAnsweredQuestionsRepository answeredQuestionsRepository)
        {
            this.applicantsProgressRepository = applicantsProgressRepository;
            this.applicationsRepository = applicationsRepository;
            this.positionsRepository = positionsRepository;
            this.jobsRepository = jobsRepository;
            this.jobHistoriesRepository = jobHistoriesRepository;
            this.personalReferencesRepository = personalReferencesRepository;
            this.educationsRepository = educationsRepository;
            this.questionnaireEntriesRepository = questionnaireEntriesRepository;
            this.questionsRepository = questionsRepository;
            this.answersRepository = answersRepository;
            this.answeredQuestionsRepository = answeredQuestionsRepository;
        }

        // This is just a wrapper for the query to get a applicantProgress given an id.
        private ApplicantProgress GetApplicantsProgress(int applicantProgressID)
        {
            ApplicantProgress applicantProgress = (from ap in applicantsProgressRepository.ApplicantsProgress
                                 where ap.ApplicantProgressID == applicantProgressID
                                 select ap).First();
            return applicantProgress;
        }

        // This is just a wrapper for the query to get a application given an id.
        private Application GetApplication(int applicationID)
        {
            Application application = (from a in applicationsRepository.Applications
                             where a.ApplicationID == applicationID
                             select a).First();
            return application;
        }

        // This is just a wrapper for the query to get a position given an id.
        private Position GetPosition(int? positionID)
        {
            Position position = (from p in positionsRepository.Positions
                                       where p.PositionID == positionID
                                       select p).First();
            return position;
        }

        // This is just a wrapper for the query to get a job given an id.
        private Job GetJob(int jobID)
        {
            Job job = (from j in jobsRepository.Jobs
                                       where j.JobID == jobID
                                       select j).First();
            return job;
        }

        // Provides list of applicants in need of interview in repository as model to Index view.
        public ActionResult Index()
        {
            List<Application> applicants = new List<Application>(); // Get applicants awaiting phone interview.
            foreach (ApplicantProgress a in applicantsProgressRepository.ApplicantsProgress)
                if (a.HadPhoneInterview == false && passed(a.ApplicationID))
                    applicants.Add(GetApplication(a.ApplicationID));

            foreach (Application a in applicants) // Get rid of applicants applying for three filled positions.
            {
                if (GetPosition(a.Position1).Filled == 1)
                    if (GetPosition(a.Position2).Filled == 1)
                        if (GetPosition(a.Position3).Filled == 1)
                            applicants.Remove(a);
            }

            return View(applicants);
        }

        // Edit command for http get, returns a application given an id
        // and passes the question to the view.
        [AcceptVerbs(HttpVerbs.Get)]
        public ViewResult Interview(int applicationID)
        {
            Application application = GetApplication(applicationID);
            TempData["currentapp"] = applicationID;
            TempData["p1"] = GetJob(GetPosition(application.Position1).JobID).JobTitle;
            if (application.Position2 != null)
                TempData["p2"] = GetJob(GetPosition(application.Position2).JobID).JobTitle;
            if (application.Position3 != null)
                TempData["p3"] = GetJob(GetPosition(application.Position3).JobID).JobTitle;

            return View(application);
        }

        // Edit command for post, places a application from the view into
        // the repository.
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Interview(Application application)
        {
                // Also saves whether the applicant passes or failed the interview.
                ApplicantProgress ap = new ApplicantProgress();
                foreach (ApplicantProgress a in applicantsProgressRepository.ApplicantsProgress)
                    if (a.ApplicationID == (int)TempData["currentapp"])
                        ap = a;
                ap.HadPhoneInterview = true;

                var checkbox = Request.Form["Pass"];
                if (checkbox != "false")
                    ap.PassedPhoneInterview = true;
                else
                    ap.PassedPhoneInterview = false;

                applicantsProgressRepository.Save();
                applicationsRepository.SaveApplication(application);
                return RedirectToAction("Index");
        }

        // Open up a page to view the applicants job history.
        public ActionResult ViewJobs(int id)
        {
            List<JobHistory> pastJobs = new List<JobHistory>();
            foreach (JobHistory jh in jobHistoriesRepository.JobHistories)
                if (jh.ApplicationID == id)
                    pastJobs.Add(jh);

            return View(pastJobs);
        }

        // Open up a page to view the applicants personal references.
        public ActionResult ViewReferences(int id)
        {
            List<PersonalReference> references = new List<PersonalReference>();
            foreach (PersonalReference pr in personalReferencesRepository.PersonalReferences)
                if (pr.ApplicationID == id)
                    references.Add(pr);

            return View(references);
        }

        // Open up a page to view the applicants education history.
        public ActionResult ViewSchools(int id)
        {
            List<Education> pastSchools = new List<Education>();
            foreach (Education e in educationsRepository.Educations)
                if (e.ApplicationID == id)
                    pastSchools.Add(e);

            return View(pastSchools);
        }

        private bool passed(int applicationID)
        {
            int minimumScore = 0;
            int score = 0;

            List<AnsweredQuestion> answeredQuestions = new List<AnsweredQuestion>();
            answeredQuestions.AddRange((from aq in answeredQuestionsRepository.AnsweredQuestions
                                        where aq.ApplicationID == applicationID
                                        select aq).ToList());
            answeredQuestions = answeredQuestions.Distinct().ToList();

            foreach (AnsweredQuestion aq in answeredQuestions)
            {
                //add the minimum score to the total
                //get the questionID
                int questionID = (from qe in questionnaireEntriesRepository.QuestionnaireEntries
                                  where qe.QuestionnaireEntryID == aq.QuestionEntryID
                                  select qe.QuestionID).First();

                //get the minimum score from the question
                minimumScore += (from q in questionsRepository.Questions
                                 where q.QuestionID == questionID
                                 select q.Minimum_Score).First();

                //get the answered question's score and add it to the total
                score += (from a in answersRepository.Answers
                          where a.AnswerID == aq.AnswerID
                          select a.Value).First();
            }

            return score >= minimumScore;
        }
    }
}